home *** CD-ROM | disk | FTP | other *** search
/ PC World 2008 September / PCWorld_2008-09_cd.bin / v cisle / sadanastroju / lightning-0.8-tb-win.xpi / js / calHtmlExport.js < prev    next >
Encoding:
JavaScript  |  2007-06-29  |  8.5 KB  |  231 lines

  1. /* -*- Mode: javascript; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  2.  * ***** BEGIN LICENSE BLOCK *****
  3.  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  4.  *
  5.  * The contents of this file are subject to the Mozilla Public License Version
  6.  * 1.1 (the "License"); you may not use this file except in compliance with
  7.  * the License. You may obtain a copy of the License at
  8.  * http://www.mozilla.org/MPL/
  9.  *
  10.  * Software distributed under the License is distributed on an "AS IS" basis,
  11.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  12.  * for the specific language governing rights and limitations under the
  13.  * License.
  14.  *
  15.  * The Original Code is Mozilla Calendar code.
  16.  *
  17.  * The Initial Developer of the Original Code is
  18.  * ArentJan Banck <ajbanck@planet.nl>.
  19.  * Portions created by the Initial Developer are Copyright (C) 2002
  20.  * the Initial Developer. All Rights Reserved.
  21.  *
  22.  * Contributor(s):
  23.  *   Michiel van Leeuwen <mvl@exedo.nl>
  24.  *   Daniel Boelzle <daniel.boelzle@sun.com>
  25.  *
  26.  * Alternatively, the contents of this file may be used under the terms of
  27.  * either the GNU General Public License Version 2 or later (the "GPL"), or
  28.  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  29.  * in which case the provisions of the GPL or the LGPL are applicable instead
  30.  * of those above. If you wish to allow use of your version of this file only
  31.  * under the terms of either the GPL or the LGPL, and not to allow others to
  32.  * use your version of this file under the terms of the MPL, indicate your
  33.  * decision by deleting the provisions above and replace them with the notice
  34.  * and other provisions required by the GPL or the LGPL. If you do not delete
  35.  * the provisions above, a recipient may use your version of this file under
  36.  * the terms of any one of the MPL, the GPL or the LGPL.
  37.  *
  38.  * ***** END LICENSE BLOCK ***** */
  39.  
  40. // Export
  41.  
  42. function calHtmlExporter() {
  43.     this.wrappedJSObject = this;
  44. }
  45.  
  46. calHtmlExporter.prototype.QueryInterface =
  47. function QueryInterface(aIID) {
  48.     if (!aIID.equals(Components.interfaces.nsISupports) &&
  49.         !aIID.equals(Components.interfaces.calIExporter)) {
  50.         throw Components.results.NS_ERROR_NO_INTERFACE;
  51.     }
  52.  
  53.     return this;
  54. };
  55.  
  56. calHtmlExporter.prototype.getFileTypes =
  57. function getFileTypes(aCount) {
  58.     aCount.value = 1;
  59.     var wildmat = '*.html; *.htm';
  60.     var label = calGetString("calendar", 'filterHtml', [wildmat]);
  61.     return([{defaultExtension:'html', 
  62.              extensionFilter: wildmat, 
  63.              description: label}]);
  64. };
  65.  
  66. // not prototype.export. export is reserved.
  67. calHtmlExporter.prototype.exportToStream =
  68. function html_exportToStream(aStream, aCount, aItems, aTitle) {
  69.     var dateFormatter = 
  70.         Components.classes["@mozilla.org/calendar/datetime-formatter;1"]
  71.                   .getService(Components.interfaces.calIDateTimeFormatter);
  72.  
  73.     var documentTitle = aTitle;
  74.     if (!documentTitle) {
  75.         documentTitle = calGetString("calendar", "HTMLTitle");
  76.     }
  77.  
  78.     var html =
  79.         <html>
  80.             <head>
  81.                 <title>{documentTitle}</title>
  82.                 <meta http-equiv='Content-Type' content='text/html; charset=UTF-8'/>
  83.                 <style type='text/css'/>
  84.             </head>
  85.             <body>
  86.                 <!-- Note on the use of the summarykey class: this is a
  87.                      special class, because in the default style, it is hidden.
  88.                      The div is still included for those that want a different
  89.                      style, where the key is visible -->
  90.             </body>
  91.         </html>;
  92.     // XXX The html comment above won't propagate to the resulting html.
  93.     //     Should fix that, one day.
  94.  
  95.     // Using this way to create the styles, because { and } are special chars
  96.     // in e4x. They have to be escaped, which doesn't improve readability
  97.     html.head.style = ".vevent {border: 1px solid black; padding: 0px; margin-bottom: 10px;}\n";
  98.     html.head.style += "div.key {font-style: italic; margin-left: 3px;}\n";
  99.     html.head.style += "div.value {margin-left: 20px;}\n";
  100.     html.head.style += "abbr {border: none;}\n";
  101.     html.head.style += ".summarykey {display: none;}\n";
  102.     html.head.style += "div.summary {background: lightgray; font-weight: bold; margin: 0px; padding: 3px;}\n";
  103.  
  104.     // Sort aItems
  105.     function sortFunc(a, b) {
  106.         var start_a = calGetStartDate(a);
  107.         if (!start_a) {
  108.             return -1;
  109.         }
  110.         var start_b = calGetStartDate(b);
  111.         if (!start_b) {
  112.             return 1;
  113.         }
  114.         return start_a.compare(start_b);
  115.     }
  116.     aItems.sort(sortFunc);
  117.  
  118.     var prefixTitle = calGetString("calendar", "htmlPrefixTitle");
  119.     var prefixWhen = calGetString("calendar", "htmlPrefixWhen");
  120.     var prefixLocation = calGetString("calendar", "htmlPrefixLocation");
  121.     var prefixDescription = calGetString("calendar", "htmlPrefixDescription");
  122.     var defaultTimezone = calendarDefaultTimezone();
  123.  
  124.     for (var pos = 0; pos < aItems.length; ++pos) {
  125.         var item = aItems[pos];
  126.  
  127.         // Put properties of the event in a definition list
  128.         // Use hCalendar classes as bonus
  129.         var ev = <div class='vevent'/>;
  130.  
  131.         // Title
  132.         ev.appendChild(
  133.             <div>
  134.                 <div class='key summarykey'>{prefixTitle}</div>
  135.                 <div class='value summary'>{item.title}</div>
  136.             </div>
  137.         );
  138.  
  139.         var startDate = calGetStartDate(item);
  140.         var endDate = calGetEndDate(item);
  141.         if (startDate) {
  142.             startDate = startDate.getInTimezone(defaultTimezone);
  143.         }
  144.         if (endDate) {
  145.             endDate = endDate.getInTimezone(defaultTimezone);
  146.         }
  147.  
  148.         // Start and end
  149.         var startstr = new Object();
  150.         var endstr = new Object();
  151.         if (startDate && endDate)
  152.             dateFormatter.formatInterval(startDate, endDate, startstr, endstr);
  153.         else {
  154.             startstr.value = "";
  155.             endstr.value = "";
  156.         }
  157.  
  158.         // Include the end date anyway, even when empty, because the dtend
  159.         // class should be there, for hCalendar goodness.
  160.         var seperator = "";
  161.         if (endstr.value) {
  162.             seperator = " - ";
  163.         }
  164.  
  165.         ev.appendChild(
  166.             <div>
  167.                 <div class='key'>{prefixWhen}</div>
  168.                 <div class='value'>
  169.                     <abbr class='dtstart' title={startDate ? startDate.icalString : "none"}>{startstr.value}</abbr>
  170.                     {seperator}
  171.                     <abbr class='dtend' title={endDate ? endDate.icalString : "none"}>{endstr.value}</abbr>
  172.                 </div>
  173.             </div>
  174.         );
  175.  
  176.  
  177.         // Location
  178.         if (item.getProperty('LOCATION')) {
  179.             ev.appendChild(
  180.                 <div>
  181.                     <div class='key'>{prefixLocation}</div>
  182.                     <div class='value location'>{item.getProperty('LOCATION')}</div>
  183.                 </div>
  184.             );
  185.         }
  186.  
  187.         // Description, inside a pre to preserve formating when needed.
  188.         var desc = item.getProperty('DESCRIPTION');
  189.         if (desc && desc.length > 0) { 
  190.             var usePre = false;
  191.             if (desc.indexOf("\n ") >= 0 || desc.indexOf("\n\t") >= 0 ||
  192.                 desc.indexOf(" ") == 0 || desc.indexOf("\t") == 0)
  193.                 // (RegExp /^[ \t]/ doesn't work.)
  194.                 // contains indented preformatted text after beginning or newline
  195.                 // so preserve indentation with PRE.
  196.                 usePre = true;
  197.  
  198.             var descnode = 
  199.                 <div>
  200.                     <div class='key'>{prefixDescription}</div>
  201.                     <div class='value'/>
  202.                 </div>;
  203.  
  204.             if (usePre) {
  205.                 descnode.div[1] = <pre class='description'>{desc}</pre>;
  206.             } else {
  207.                 var lines = desc.split('\n');
  208.                 for (var i in lines) {
  209.                     descnode.div[1].appendChild(lines[i]);
  210.                     // Add a new line, except after the last line
  211.                     if (i != (lines.length-1)) {
  212.                         descnode.div[1].appendChild(<br/>);
  213.                     }
  214.                 }
  215.             }
  216.             ev.appendChild(descnode);
  217.         }
  218.         html.body.appendChild(ev);
  219.     }
  220.  
  221.     // Convert the javascript string to an array of bytes, using the
  222.     // utf8 encoder
  223.     var convStream = Components.classes["@mozilla.org/intl/converter-output-stream;1"]
  224.                                .getService(Components.interfaces.nsIConverterOutputStream);
  225.     convStream.init(aStream, 'UTF-8', 0, 0x0000);
  226.  
  227.     var str = html.toXMLString()
  228.     convStream.writeString(str);
  229.     return;
  230. };
  231.